<?php
	/*
	
	Database class
	(c) 2009 Giel Berkers
	----------------------------------------------------------------------------
	Usage:
	
	$db = db::getInstance();
	
	$db->init($dbuser, $dbpass, $dbhost, $dbname)
	
	$db->setPrefix($prefix);
	
	$numberOfResults = $db->total($table [, $where]);
	$singleValue     = $db->get($table, $where);
	$result          = $db->select($what, $table [, $arguments]);
	
	$db->insert($table, $values);
	$db->update($table, $values [, $where]);
	$db->delete($table, $where);
	----------------------------------------------------------------------------
	Created with the singleton design pattern
	----------------------------------------------------------------------------
	
	*/
	
	class db
	{
		private $dbprefix = '';
		private static $instance;

		private function __construct() {
			
		}
		
		public static function getInstance() {
			if(!self::$instance) {
				self::$instance = new db();
			}
			return self::$instance;
		}
		
		/**
		 * Make a persistent connection with the database
		 *
		 * @param string $dbuser	Username
		 * @param string $dbpass	Password
		 * @param string $dbhost	Host
		 * @param string $dbname	Database name
		 */
		public function init($dbuser, $dbpass, $dbhost, $dbname) {	
			$link = mysql_pconnect($dbhost, $dbuser, $dbpass);
			$ok   = mysql_select_db($dbname, $link);
			if(!$ok) {
				// Database does not exists.
				die('Error: Database does not exist!');
			}			
		}
		
		/**
		 * Set the prefix of the tables
		 *
		 * @param string $dbprefix		The prefix
		 */
		public function setPrefix($dbprefix) {
			$this->dbprefix = $dbprefix;
		}
		
		/**
		 * Get the prefix
		 *
		 * @return unknown				The prefix
		 */
		public function getPrefix() {
			return $this->dbprefix;
		}
		
		/**
		 * Do a SQL Query
		 *
		 * @param string $sql			The SQL Query
		 * @return unknown				The result
		 */
		public function mq($sql) {
			$result = mysql_query($sql) or die('MySQL Error: '.mysql_error().'<br />Query:<br /><code>'.$sql.'</code>');
			return $result;
		}
		
		/**
		 * Do a SQL Query and return the array
		 *
		 * @param string $sql			The SQL Query
		 * @param string $type			The type (assoc, row, or array)
		 * @return array				The array
		 */
		public function ma($sql, $type = 'assoc') {
			if(is_string($sql)) {
				$result = $this->mq($sql);
			} else {
				$result = $sql;
			}
			if(mysql_num_rows($result)>0) {
				switch($type) {
					case 'assoc' :
						{
							$a = mysql_fetch_assoc($result);
							break;
						}
					case 'row' :
						{
							$a = mysql_fetch_row($result);
							break;
						}
					default:
						{
							$a = mysql_fetch_array($result);
							break;
						}
				}			
			} else {
				return false;
			}
			return $a;
		}
		
		/**
		 * Do a SQL Query and return a single result
		 *
		 * @param string $sql			The SQL Query
		 * @return unknown				The single result
		 */
		public function sr($sql) {
			$row = $this->ma($sql, 'row');
			if($row!=false) {
				return $row[0];
			} else {
				return false;
			}
		}
		
		/**
		 * Count the total number of occurances in a table
		 *
		 * @param string $tablename			The name of the table
		 * @param array $args				The arguments (array("id"=>12, "name"=>'hello')
		 * @return unknown					The amount
		 */
		public function total($tablename, $args = null) {
			$sql = 'SELECT COUNT(*) AS `total` FROM `'.$this->dbprefix.$tablename.'`';
			if($args!=null) {
				$sql .= ' WHERE ';
				$first = true;		
				foreach($args as $key=>$val) {
					if(!$first) { $sql .= ' AND '; }
					$sql .= ' `'.$key.'` = \''.$val.'\' ';
					$first = false;
				}
			}
			$sql .= ';';
			return $this->sr($sql);
		}		

		/**
		 * Select data from the database
		 *
		 * @param unknown_type $what		An array with the fields to select, a comma seperated list or '*' to select all
		 * @param string $table				The name of the table
		 * @param array $args				Optional arguments: where(array), orderby(array), order(string), limit(int)
		 * @return unknown					The result
		 */
		public function select($what, $table, $args=null) {
			if($args==null) { $args=array(); }
			$where = isset($args['where']) ? $args['where'] : null;
			$orderby = isset($args['orderby']) ? $args['orderby'] : null;
			$order = isset($args['order']) ? $args['order'] : null;
			$limit = isset($args['limit']) ? $args['limit'] : null;
			$sql = 'SELECT ';
			if(is_string($what)) {
				if($what=='*') {
					$sql .= '*';
				} else {
					// $sql .= '`'.$what.'`';
					$what = explode(',', $what);
				}
			}
			if(is_array($what)) {
				$first = true;
				foreach($what as $key) {
					if(!$first) { $sql .= ', '; }
					$sql .= '`'.$key.'`';
					$first = false;
				}
			}
			$sql .= ' FROM `'.$this->dbprefix.$table.'`';
			if($where!=null) {				
				$sql .= ' WHERE ';
				$first = true;
				foreach($where as $key=>$value) {
					if(!$first) { $sql .= ' AND '; }
					$sql .= '`'.$key.'`=\''.$value.'\'';					
					$first = false;
				}
			}
			if($orderby!=null) {
				$sql .= ' ORDER BY ';
				if(is_string($orderby)) {
					$sql .= '`'.$orderby.'`';
				} elseif(is_array($orderby)) {
					$first = true;				
					foreach($orderby as $key) {
						if(!$first) { $sql .= ', '; }
						$sql .= '`'.$key.'`';
						$first = false;
					}
				}
			}
			if($order!=null) {
				$sql .= ' '.strtoupper($order);
			}
			if($limit!=null) {
				$sql .= ' LIMIT '.$limit;
			}
			$sql .= ';';
			$result = $this->mq($sql);
			return $result;
		}	
		
		/**
		 * Insert data into the database
		 * 
		 * @param string $table		The name of the table
		 * @param array $array		An associated array with values to insert
		 */
		public function insert($table, $array) {
			$keys = array_keys($array);
			$first = true;
			$sql = 'INSERT INTO `'.$this->dbprefix.$table.'` (';
			foreach($keys as $key) {
				if(!$first) { $sql .= ', '; }
				$sql .= '`'.$key.'`';
				$first = false;
			}
			$sql .= ') VALUES (';
			$first = true;
			foreach($keys as $key) {
				if(!$first) { $sql .= ', '; }
				$sql .= '\''.$array[$key].'\'';
				$first = false;
			}
			$sql .= ');';
			$this->mq($sql);
		}
		
		/**
		 * Function to update data in the database:
		 *
		 * @param string $table		The name of the table
		 * @param array $array		The values to update
		 * @param array $where		Where-statement
		 */
		public function update($table, $array, $where=null) {
			$keys = array_keys($array);
			$first = true;
			$sql = 'UPDATE `'.$this->dbprefix.$table.'` SET ';
			foreach($keys as $key) {
				if(!$first) { $sql .= ', '; }
				$sql .= '`'.$key.'`=\''.$array[$key].'\'';
				$first = false;
			}
			if($where!=null) {
				$sql .= ' WHERE ';
				$first = true;
				$keys = array_keys($where);
				foreach($keys as $key) {
					if(!$first) { $sql .= ' AND '; }
					$sql .= '`'.$key.'`=\''.$where[$key].'\'';
					$first = false;
				}
			}
			$sql .= ';';
			$this->mq($sql);
		}
		
		/**
		 * Function to delete data from the database:
		 *
		 * @param string $table		The name of the table
		 * @param array $where		Where statement
		 */
		public function delete($table, $where) {
			$sql = 'DELETE FROM `'.$this->dbprefix.$table.'` WHERE ';
			$first = true;
			$keys = array_keys($where);
			foreach($keys as $key) {
				if(!$first) { $sql .= ' AND '; }
				$sql .= '`'.$key.'`=\''.$where[$key].'\'';
				$first = false;
			}
			$sql .= ';';
			$this->mq($sql);
		}
		
		/**
		 * Function to retrieve a single result:
		 *
		 *
		 * @param unknown_type $what		An array with the fields to select or '*' to select all
		 * @param string $table				The name of the table
		 * @param array $where				Where statement
		 * @return unknown					The result on success, or false on failure
		 */
		public function get($what, $table, $where=null) {
			$sql = 'SELECT `'.$what.'` FROM `'.$this->dbprefix.$table.'`';
			if($where!=null) {
				$sql .= ' WHERE ';
				$first = true;
				$keys = array_keys($where);
				foreach($keys as $key) {
					if(!$first) { $sql .= ' AND '; }
					$sql .= '`'.$key.'`=\''.$where[$key].'\'';
					$first = false;
				}
			}
			$sql .= ';';
			$a = $this->ma($sql, 'row');
			if($a!=false) {
				return $a[0];
			} else {
				return false;
			}
		}		
	}
?>